/*
 * Copyright 2006 Google Inc.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package com.gwthtml.ui.client;

import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.ui.ChangeListener;
import com.google.gwt.user.client.ui.ChangeListenerCollection;
import com.google.gwt.user.client.ui.ClickListener;
import com.google.gwt.user.client.ui.ClickListenerCollection;
import com.google.gwt.user.client.ui.FocusWidget;
import com.google.gwt.user.client.ui.HasName;
import com.google.gwt.user.client.ui.HasText;
import com.google.gwt.user.client.ui.KeyboardListener;
import com.google.gwt.user.client.ui.KeyboardListenerCollection;
import com.google.gwt.user.client.ui.SourcesChangeEvents;
import com.google.gwt.user.client.ui.SourcesClickEvents;
import com.google.gwt.user.client.ui.SourcesKeyboardEvents;
import com.google.gwt.user.client.ui.impl.TextBoxImpl;

/**
 * Abstract base class for all text entry widgets.
 */
public class HtmlTextBoxBase extends FocusWidget implements 
    SourcesChangeEvents, HasText, HasName {

  /**
   * Text alignment constant, used in
   * {@link TextBoxBase#setTextAlignment(TextBoxBase.TextAlignConstant)}.
   */
  public static class TextAlignConstant {
    private String textAlignString;

    private TextAlignConstant(String textAlignString) {
      this.textAlignString = textAlignString;
    }

    private String getTextAlignString() {
      return textAlignString;
    }
  }

  /**
   * Center the text.
   */
  public static final TextAlignConstant ALIGN_CENTER = new TextAlignConstant(
      "center");

  /**
   * Justify the text.
   */
  public static final TextAlignConstant ALIGN_JUSTIFY = new TextAlignConstant(
      "justify");

  /**
   * Align the text to the left edge.
   */
  public static final TextAlignConstant ALIGN_LEFT = new TextAlignConstant(
      "left");

  /**
   * Align the text to the right.
   */
  public static final TextAlignConstant ALIGN_RIGHT = new TextAlignConstant(
      "right");

  private ChangeListenerCollection changeListeners;

  /**
   * Creates a text box that wraps the given browser element handle. This is
   * only used by subclasses.
   * 
   * @param elem the browser element to wrap
   */
  protected HtmlTextBoxBase(Element elem) {
    super(elem);
    sinkEvents(Event.ONCHANGE);
    setName("htb_"+getElement().hashCode());	
  }

  public void addChangeListener(ChangeListener listener) {
    if (changeListeners == null) {
      changeListeners = new ChangeListenerCollection();
    }
    changeListeners.add(listener);
  }

  public String getName() {
    return DOM.getAttribute(getElement(), "name");
  }

  public String getText() {
    return DOM.getAttribute(getElement(), "value");
  }

  public void onBrowserEvent(Event event) {
    // Call the superclass' implementation first (because FocusWidget fires
    // some events itself).
    super.onBrowserEvent(event);

    int type = DOM.eventGetType(event);
    if (type == Event.ONCHANGE) {
      // Fire the change event.
      if (changeListeners != null) {
        changeListeners.fireChange(this);
      }
    }
  }

  public void removeChangeListener(ChangeListener listener) {
    if (changeListeners != null) {
      changeListeners.remove(listener);
    }
  }

  public void setName(String name) {
    DOM.setAttribute(getElement(), "name", name);
  }

  public void setText(String text) {
    DOM.setAttribute(getElement(), "value", text);
  }

  /**
   * Sets the alignment of the text in the text box.
   * 
   * @param align the text alignment (as specified by {@link #ALIGN_CENTER},
   *          {@link #ALIGN_JUSTIFY}, {@link #ALIGN_LEFT}, and
   *          {@link #ALIGN_RIGHT})
   */
  public void setTextAlignment(TextAlignConstant align) {
    DOM.setStyleAttribute(getElement(), "textAlign", align.getTextAlignString());
  }
}